from django.shortcuts import render
from django.views import View
from utils.my_category import get_categories, get_crumbs
from . import models
from django.core.paginator import Paginator
from django import http
from utils.response_code import *
from django.conf import settings
import time
from datetime import datetime
from utils.base_views import BaseViews


class ListView(View):
    """
    按照商品创建时间排序,数据序列化后分页
        http://www.meiduo.site:8000/list/115/1/?sort=default
        # 按照商品价格由低到高排序
        http://www.meiduo.site:8000/list/115/1/?sort=price
        # 按照商品销量由高到低排序
        http://www.meiduo.site:8000/list/115/1/?sort=hot
    """

    def get(self, request, category_id, page_num):
        # 商品频道分类
        categories = get_categories()
        # 面包屑导航
        try:
            category = models.GoodsCategory.objects.get(id=category_id)
        except Exception as e:
            return http.HttpResponseForbidden("缺少参数，或请确认连接是否正确")

        # 列表数据过滤排⾏
        sort = request.GET.get('sort', 'default')
        #  根据sort设置排序⽅式
        if sort == 'price':
            # sort_field 字段是为查数据库order_by分类准备的
            sort_field = '-price'
            sort = 'price'
        elif sort == 'hot':
            sort_field = '-sales'
            sort = 'hot'
        else:
            sort_field = '-create_time'
            sort = "default"
        skus = models.SKU.objects.filter(category_id=category_id, is_launched=True).order_by(sort_field)
        # 创建分页器
        paginator = Paginator(skus, 5)  # 创建分页器，每页5条
        try:
            page = paginator.page(page_num)  # 获取当前页数据
        except BaseException as e:
            return http.HttpResponseNotFound(e)
        skuslist = page.object_list  # 获取在当前这页上的对象列表。
        number = page.number  # 获取当前页数
        total_page = paginator.num_pages  # 总页数

        context = {
            'categories': categories,
            'category': category,
            'skuslist': skuslist,  # 获取在当前这页上的对象列表。
            'number': number,  # 获取当前页数
            'total_page': total_page,  # 总页数
            "sort": sort,  # 排序字段
        }
        return render(request, 'list.html', context=context)


class HotView(View):
    """热销数据"""

    def get(self, request, category_id):
        hot_sku = models.SKU.objects.filter(category_id=category_id).order_by('-sales')[:3]
        # 组装数据
        hot_sku_list = []
        for sku in hot_sku:
            sku.default_image_url = settings.FDFS_BASE_URL + sku.default_image_url
            hot_sku_list.append(
                {'id': sku.id, 'default_image_url': sku.default_image_url, 'name': sku.name, 'price': sku.price})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': err_msg[RETCODE.OK], 'hot_sku_list': hot_sku_list})


class SKUDetailView(View):
    """商品详情页"""

    def get(self, request, sku_id):
        # 商品频道分类
        categories = get_categories()
        # 面包屑
        category = get_crumbs(sku_id)
        # 获取当前sku的信息
        try:
            sku = models.SKU.objects.get(id=int(sku_id))
        except models.SKU.DoesNotExist:
            return http.HttpResponseForbidden()
        # todo 未理解
        # 查询和渲染SKU规格信息
        sku_specs = sku.specs.order_by('-spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()  # 通过外键查找关联的数据再反向查找
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('-spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        # 渲染页面
        context = {
            'categories': categories,
            'category': category,
            'sku': sku,
            'specs': goods_specs,
        }
        return render(request, 'detail.html', context=context)


class GoodsVisitView(View):
    """统计分类商品访问量"""

    def post(self, request, category_id):
        try:
            category = models.GoodsCategory.objects.get(id=category_id)
        except models.GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('分类不存在')
        # 获取今天的日期
        t = time.localtime()
        today_str = "%d-%02d-%02d" % (t.tm_year, t.tm_mon, t.tm_mday)  # 时间为字符串
        today_date = datetime.strptime(today_str, '%Y-%m-%d')  # 将时间修改为date类型
        try:
            # 查询今天该类别商品访问量
            counts_data = category.goodsvisitcount_set.get(date=today_date)
        except:
            # 如果该类别今天没有就新建一个
            counts_data = models.GoodsVisitCount()
        try:
            """
            如果访问记录存在，说明今天不是第一次访问，不新建记录，访问量直接累加。
            如果访问记录不存在，说明今天是第一次访问，新建记录并保存访问量。
            """
            counts_data.category = category
            counts_data.count += 1
            counts_data.date = today_date
            counts_data.save()
        except Exception as e:
            return http.HttpResponseServerError(e)

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})
